local function GetStringsTable()
    return TUNING.NPC_CHAT_TABLE[ type(TUNING.__NPC_LANGUAGE)=="function" and TUNING.__NPC_LANGUAGE() or TUNING.__NPC_LANGUAGE ] ["npc_item_rainbow_horn"] or {}
end


local assets =
{
    Asset("ANIM", "anim/horn.zip"),
}

local function FollowLeader(follower, leader)
    follower.sg:PushEvent("heardhorn", { musician = leader })
end

local function TryAddFollower(leader, follower)
    if leader.components.leader ~= nil and
        follower.components.follower ~= nil and
        follower:HasTag("beefalo") and not follower:HasTag("baby") and
        leader.components.leader:CountFollowers("beefalo") < TUNING.HORN_MAX_FOLLOWERS then
        leader.components.leader:AddFollower(follower)
        follower.components.follower:AddLoyaltyTime(TUNING.HORN_EFFECTIVE_TIME + math.random())
        if follower.components.combat ~= nil and follower.components.combat:TargetIs(leader) then
            follower.components.combat:SetTarget(nil)
        end
        follower:DoTaskInTime(math.random(), FollowLeader, leader)
    end
end

local function HearHorn(inst, musician, instrument)
    if musician.components.leader ~= nil and
        inst.components.herdmember ~= nil and
        inst:HasTag("beefalo") and not inst:HasTag("baby") then
        if inst.components.combat ~= nil and inst.components.combat:HasTarget() then
            inst.components.combat:GiveUp()
        end
        TryAddFollower(musician, inst)
        local herd = inst.components.herdmember:GetHerd()
        if herd ~= nil and herd.components.herd ~= nil then
            for k, v in pairs(herd.components.herd.members) do
                TryAddFollower(musician, k)
            end
        end
    end

	if inst.components.farmplanttendable ~= nil then
		inst.components.farmplanttendable:TendTo(musician)
    end
end

local function RandomVectorDelta(num)
    if num == nil or num == 0 then
        num = 1
    end
    local ret = math.random(num)
    if math.random(100) <= 50 then
        ret = -ret
    end
    return ret
end

local function upgrade_horn(inst)
    inst.components.finiteuses.Use_old = inst.components.finiteuses.Use
    inst.components.finiteuses.Use = function(self,...)
        self.inst:PushEvent("npc_event_item_used")
        self:Use_old(...)
    end


    inst:ListenForEvent("npc_event_item_used",function()
        ----------------------------------------------------
        local pt = Vector3(inst.Transform:GetWorldPosition())
        local players = TheSim:FindEntities(pt.x, 0, pt.z, 50, {"player"}, nil, nil)
        for k, temp_target in pairs(players) do
            local x = pt.x + RandomVectorDelta()*math.random(20,30)
            local z = pt.z + RandomVectorDelta()*math.random(20,30)
            SpawnPrefab("npc_projectile_rainbow"):PushEvent("Set",{
                pt = Vector3(x,0,z), 
                target = temp_target,
                owner = temp_target,
                range = 0.5,
                speed = 10,
                target_fn = function(fx_inst,owner,target)
                    if target.___npc_fx_rainbow then
                        target.___npc_fx_rainbow:Remove()
                    end
                    target.___npc_fx_rainbow = target:SpawnChild("npc_fx_rainbow")
                    if target.components.health then
                        target.components.health:DoDelta(200)

                    end

                    if target:HasTag("playerghost") then
                        target:PushEvent("respawnfromghost", { source = inst })
                        
                    end

                    fx_inst:Remove()

                end,
            })
        end
        ----------------------------------------------------
    end)

    inst.components.hauntable.onhaunt = function(inst,doer)
        if doer and doer:HasTag("player") and doer:HasTag("playerghost") then
            doer.SoundEmitter:PlaySound("dontstarve/common/horn_beefalo")
            inst:PushEvent("npc_event_item_used")
            inst:Remove()
        end
    end

end

local function fn()
    local inst = CreateEntity()

    inst.entity:AddTransform()
    inst.entity:AddAnimState()
    inst.entity:AddNetwork()

    MakeInventoryPhysics(inst)

    inst:AddTag("horn")

    --tool (from tool component) added to pristine state for optimization
    inst:AddTag("tool")

    inst.AnimState:SetBank("horn")
    inst.AnimState:SetBuild("horn")
    inst.AnimState:PlayAnimation("idle")

    MakeInventoryFloatable(inst, "med", 0.25)

    inst.entity:SetPristine()
    if not TheWorld.ismastersim then
        return inst
    end

    inst:AddComponent("inspectable")
    inst:AddComponent("instrument")
    inst.components.instrument.range = TUNING.HORN_RANGE
    inst.components.instrument:SetOnHeardFn(HearHorn)

    inst:AddComponent("tool")
    inst.components.tool:SetAction(ACTIONS.PLAY)

    inst:AddComponent("finiteuses")
    inst.components.finiteuses:SetMaxUses(5)
    inst.components.finiteuses:SetUses(5)
    inst.components.finiteuses:SetOnFinished(inst.Remove)
    inst.components.finiteuses:SetConsumption(ACTIONS.PLAY, 1)

    inst:AddComponent("inventoryitem")
    inst.components.inventoryitem:ChangeImageName("horn")
	inst.components.inventoryitem.cangoincontainer = true

    MakeHauntableLaunch(inst)
    -- inst:AddComponent("hauntable")

    inst:AddComponent("named")
    inst.components.named:SetName(GetStringsTable().name)
    -- STRINGS.NAMES[string.upper("npc_item_rainbow_horn")] = GetStringsTable().name
    STRINGS.CHARACTERS.GENERIC.DESCRIBE[string.upper("npc_item_rainbow_horn")] = GetStringsTable().inspect_str  --人物检查的描述

    inst:DoTaskInTime(0,upgrade_horn)
    return inst
end

return Prefab("npc_item_rainbow_horn", fn, assets)
